#ifndef _SHARP_ALLOC_H
#define _SHARP_ALLOC_H

#include "sharp-common.h"
#include <stdlib.h>

/**
 * @file src/alloc.c
 */

/**
 * Initialize the allocator to use the given panic function.
 * @param func a panic function
 *
 * Note that you can actually use all alloc functions even without calling this
 * function beforehand. If you don't provide a function (NULL), the panic
 * routine will be set to the internal one, which prints an error message to
 * stderr and then calls abort(). If you don't call this routine at all, an
 * empty panic function will be used that simply doesn't do anything. If your
 * program does anything remotely complicated, you will want to implement your
 * own panic function.
 * Make sure your panic function does *NOT* depend on being able to allocate
 * memory in any way or form, meaning even string copying is out of the
 * question.
 */
void sharp_alloc_init(void (*func)(void));

/**
 * Allocate some memory.
 * @param size the amount of memory in bytes to be allocated
 *
 * Allocates memory as necessary. If it fails, the panic routine set by
 * sharp_alloc_init() is called. Beware of integer overflows. Use
 * sharp_calloc() if you need to allocate space for multiple elements of the
 * same type.
 */
void *sharp_malloc(size_t size);

/**
 * Allocate memory for a certain number of members of a given size.
 * @param nmemb the amount of members to be allocated
 * @param size the size of each individual member
 */
void *sharp_calloc(size_t nmemb, size_t size);

/**
 * Reallocates a block of memory.
 * @param data pointer to the data currently residing there
 * @param size new size for the pointer
 *
 * Make sure to beware of integer overflows when using this function by calling
 * it with a multiplication like (elementnum * size)!
 */
void *sharp_realloc(void *data, size_t size);

/**
 * Duplicates a string.
 * @param s pointer to the string to be duplicated
 */
char *sharp_strdup(const char *s);

/**
 * Duplicates a string; at most a given number of bytes.
 * @param s pointer to the string to be duplicated
 * @param n number of bytes to be copied
 *
 * If n is longer than is, at most n bytes are copied and a terminal \0 is
 * added to the end of the string.
 */
char *sharp_strndup(const char *s, size_t n);

/**
 * Safely free a pointer.
 * @param ptr the pointer to be freed
 *
 * We expect free() not to fail. This also resets the pointer to be NULL.
 */
#define sharp_free(ptr) { if( ptr ) free( ptr );\
ptr = NULL; }

#endif /* _SHARP_ALLOC_H */
